package main

import (
	"cn.bytengine/stem/events"
	"cn.bytengine/stem/network/udp_socket"
	"cn.bytengine/stem/services/app_events"
	"cn.bytengine/stem/utils"
	"errors"
	"fmt"
	"github.com/panjf2000/gnet/v2"
	"net"
	"sync"
)

func init() {
	var (
		err error
	)
	err = events.RegisterAsyncSubscribe(app_events.UdpServerBoot, onServerBoot)
	if err != nil {
		fmt.Printf("[ERROR] register '%s' event listener occurred error. %+v\n", app_events.AppEventPrefix, err)
		panic(err)
	}
}

func onServerBoot(event *udp_socket.UdpServerBootEvent) {
	var (
		err           error
		conn          gnet.Conn
		client        *gnet.Client
		clientHandler = &udp_socket.ClientHandler{}
	)
	client, err = gnet.NewClient(clientHandler, gnet.WithMulticore(true), gnet.WithMulticastInterfaceIndex(ipv4InterfaceIndex))
	if err != nil {
		fmt.Printf("[ERROR] create gnet client instance occurred error: %+v\n", err)
		return
	}
	conn, err = client.Dial("udp", "230.0.0.1:1234")
	if err != nil {
		fmt.Printf("[ERROR] client Dial to multicast server occurred error: %+v\n", err)
		return
	}
	defer conn.Close()
	_, err = conn.Write([]byte("1"))
	if err != nil {
		fmt.Printf("[ERROR] client write to multicast server occurred error: %+v\n", err)
		return
	}
}

var (
	ipv4InterfaceIndex int
)

func launchServer(wg *sync.WaitGroup) {
	var (
		err          error
		netInterface *net.Interface
	)

	netInterface, err = utils.GetIPv4MacAddr()
	if err != nil {
		panic(err)
	}
	if netInterface == nil {
		panic(errors.New("not found IPv4 net interface"))
	}
	ipv4InterfaceIndex = netInterface.Index
	wg.Add(1)
	go func() {
		err = gnet.Run(&udp_socket.EchoServer{}, "udp://230.0.0.1:1234", gnet.WithMulticore(true), gnet.WithMulticastInterfaceIndex(ipv4InterfaceIndex), gnet.WithOptions(gnet.Options{}))
		if err != nil {
			panic(err)
		}
		wg.Done()
	}()
}

func main() {
	var (
		wg = &sync.WaitGroup{}
	)
	launchServer(wg)
	wg.Wait()
}
